/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once


#include "../节点.h"

#include "../插座/材质纹理插座.h"
#include "../插座/list/list矢量插座.h"


extern "C" {
	#include <libavcodec/avcodec.h>
	#include <libavformat/avformat.h>
	#include <libswscale/swscale.h>
	#include <libavutil/frame.h>
}


class API_EXPORT C_二维纹理节点 : public C_节点基类 {
	
public:
	C_二维纹理节点(S_设备环境& ctx);
	~C_二维纹理节点();

	S_Props m_纹理库;
	S_Props m_GPU纹理;
	S_Props m_像素位宽;
	S_Props m_像素通道;

	bool	f_update();
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存纹理节点(C_节点基类* n, FILE* f);




class API_EXPORT C_外部纹理节点 : public C_节点基类 {
	//std::string m_以加载文件记录;

	struct S_AV_Ctex {
		AVFormatContext*	m_格式环境;
		AVCodecContext*		m_编码环境;
		AVFrame*			m_帧;
		//AVFrame*			m_输出帧;
		SwsContext*			m_转换格式环境;
		int32				m_VideoStreamIndex;

		std::string			m_文件路径;
		S_纹理*				m_纹理;
		bool				m_已加载;

		S_AV_Ctex() {
			m_帧 = nullptr;
			m_编码环境 = nullptr;
			m_格式环境 = nullptr;
			m_转换格式环境 = nullptr;
			m_VideoStreamIndex = -1;

			m_纹理 = nullptr;
			m_已加载 = false;
		}
		~S_AV_Ctex() {
			if (m_帧) av_frame_free(&m_帧);
			if (m_编码环境) avcodec_close(m_编码环境);
			if (m_格式环境) avformat_close_input(&m_格式环境);
			if (m_转换格式环境) sws_freeContext(m_转换格式环境);
		}
	};
	
	//AVFormatContext*	m_格式环境;
	//AVCodecContext*		m_编码环境;
	//AVFrame*			m_帧;
	//AVFrame*			m_输出帧;
	//SwsContext*			m_转换格式环境;
	//int32				m_VideoStreamIndex;

public:
	C_外部纹理节点(S_设备环境& ctx);
	~C_外部纹理节点();

	//S_纹理* m_Tex;
	std::map<std::string, S_AV_Ctex> m_视频环境;

	S_Props m_序列;
	S_Props m_序列偏移;
	S_Props m_投影方式;
	S_Props m_GPU纹理;
	S_Props m_纵向反转;
	S_Props m_横向反转;

	S_Props m_资源集类型;
	S_Props m_文件数组;
	S_Props m_文件夹下所有文件;
	S_Props m_图像预设后缀;
	S_Props m_视频预设后缀;
	S_Props m_开启过滤;
	S_Props m_过滤名称;


	void	f_释放视频(S_AV_Ctex& ctx);
	bool	f_加载视频(S_AV_Ctex& ctx);
	void	f_读取视频帧(S_AV_Ctex& ctx, int32 帧);
	void	f_更新视频纹理(int32 帧);
	bool	f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建外部纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载外部纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存外部纹理节点(C_节点基类* n, FILE* f);



class API_EXPORT C_外部纹理集节点 : public C_节点基类 {
	std::string m_以加载文件记录;

public:
	C_外部纹理集节点(S_设备环境& ctx);
	~C_外部纹理集节点();

	//S_纹理* m_Tex;

	S_Props m_全部加载;
	S_Props m_过滤名称;
	S_Props m_投影方式;

	void	f_加载纹理();
	bool	f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建外部纹理集节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载外部纹理集节点(S_设备环境& ctx, FILE* f);
void		f_node_保存外部纹理集节点(C_节点基类* n, FILE* f);




class API_EXPORT C_加载纹理节点 : public C_节点基类 {
	std::string m_以加载文件记录;

public:
	C_加载纹理节点(S_设备环境& ctx);
	~C_加载纹理节点();

	//S_Props m_全部加载;
	//S_Props m_过滤名称;
	S_Props m_GPU纹理;

	bool	f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建加载纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载加载纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存加载纹理节点(C_节点基类* n, FILE* f);



class API_EXPORT C_从文件填充纹理节点 : public C_节点基类 {
	std::string m_以加载文件记录;

public:
	C_从文件填充纹理节点(S_设备环境& ctx);
	~C_从文件填充纹理节点();

	S_Props m_填充方式;
	//S_Props m_过滤名称;
	//S_Props m_GPU纹理;

	bool	f_update();
	//std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建从文件填充纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载从文件填充纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存从文件填充纹理节点(C_节点基类* n, FILE* f);



class API_EXPORT C_2D纹理采样节点 : public C_节点基类 {

public:
	C_2D纹理采样节点(S_设备环境& ctx);
	~C_2D纹理采样节点();

	S_Props m_投影方式;
	S_Props m_采样方式;
	//S_Props m_瓦片数量;

	bool        f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建纹理采样节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载纹理采样节点(S_设备环境& ctx, FILE* f);
void		f_node_保存纹理采样节点(C_节点基类* n, FILE* f);



class API_EXPORT C_2D纹理数组采样节点 : public C_节点基类 {

public:
	C_2D纹理数组采样节点(S_设备环境& ctx);
	~C_2D纹理数组采样节点();

	S_Props m_投影方式;
	S_Props m_采样方式;

	bool        f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建2D纹理数组采样节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载2D纹理数组采样节点(S_设备环境& ctx, FILE* f);
void		f_node_保存2D纹理数组采样节点(C_节点基类* n, FILE* f);




class API_EXPORT C_流视频节点 : public C_节点基类 {
	//cv::MultiTracker m_跟踪器;
	uint8		m_跟踪点数量;
public:
	C_流视频节点(S_设备环境& ctx);
	~C_流视频节点();

	//=============== 跟踪类 =================
	
	//S_结构对象指针	m_跟踪器;
	S_结构指针	m_初始帧;
	S_结构指针	m_帧;



	//======= 特征提取 =======
	S_Operator*	m_Ops特效提取;

	int32 m_阈值步长;
	int32 m_起始阈值;
	int32 m_终止阈值;
	int32 m_重复的最小次数;
	int32 m_最小的斑点距离;

	bool	m_斑点颜色限制;
	uint8	m_斑点灰度;

	bool	m_斑点面积限制;
	int32	m_斑点最小面积;
	int32	m_斑点最大面积;

	bool	m_斑点圆度限制;
	float32	m_斑点最小圆度;
	float32	m_斑点最大圆度;

	bool	m_斑点惯性率限制;
	float32	m_斑点最小惯性率;
	float32	m_斑点最大惯性率;

	bool	m_斑点凸度限制;
	float32	m_斑点最小凸度;
	float32	m_斑点最大凸度;





	float32		m_伽马;
	S_Props		m_Prop伽马;

	float32		m_亮度;
	S_Props		m_Prop亮度;
	float32		m_对比度;
	S_Props		m_Prop对比度;



	bool	f_update();
	
	// CSRT BOOSTING MIL KCF TLD MEDIANFLOW GOTURN MOSSE
	void					f_set跟踪器类型(std::string type);
	//cv::Ptr<cv::Tracker>	f_create跟踪器类型(std::string type);
	void					f_init跟踪器坐标(const vec2& coord, const vec2& size);
	std::vector<S_Rect2Df>	f_模板探测跟踪点(const vec2& coord, const vec2& size);

	
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};



C_节点基类* f_node_加载流视频节点(S_设备环境& ctx, FILE* f);





class API_EXPORT C_噪波纹理节点 : public C_节点基类 {

public:
	C_噪波纹理节点(S_设备环境& ctx);
	~C_噪波纹理节点();

	S_Props		m_过程纹理属性;
	//S_Props		m_偏移;
	//S_Props		m_缩放;
	//S_Props		m_强度;
	S_Props		m_通道数量;
	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
	void    f_Copy(const C_节点基类* node);
};

C_节点基类* f_node_创建噪波纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载噪波纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存噪波纹理节点(C_节点基类* n, FILE* f);



class API_EXPORT C_渐变纹理节点 : public C_节点基类 {

public:
	C_渐变纹理节点(S_设备环境& ctx);
	~C_渐变纹理节点();

	S_Props		m_类型;
	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建渐变纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载渐变纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存渐变纹理节点(C_节点基类* n, FILE* f);



class API_EXPORT C_棋盘格纹理节点 : public C_节点基类 {

public:
	C_棋盘格纹理节点(S_设备环境& ctx);
	~C_棋盘格纹理节点();


	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建棋盘格纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载棋盘格纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存棋盘格纹理节点(C_节点基类* n, FILE* f);



class API_EXPORT C_字符纹理节点 : public C_节点基类 {
	std::string m_以加载文件记录;
	S_纹理*		m_字符纹理;
	S_字体		m_字体;
public:
	C_字符纹理节点(S_设备环境& ctx);
	~C_字符纹理节点();

	S_Props m_字体文件;
	S_Props m_预设字符类型;

	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建字符纹理节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载字符纹理节点(S_设备环境& ctx, FILE* f);
void		f_node_保存字符纹理节点(C_节点基类* n, FILE* f);



class API_EXPORT C_纹理UV坐标节点 : public C_节点基类 {

public:
	C_纹理UV坐标节点(S_设备环境& ctx);
	~C_纹理UV坐标节点();

	S_Props m_坐标类型;

	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建纹理UV坐标节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载纹理UV坐标节点(S_设备环境& ctx, FILE* f);
void		f_node_保存纹理UV坐标节点(C_节点基类* n, FILE* f);



class API_EXPORT C_字符纹理坐标节点 : public C_节点基类 {
	
public:
	C_字符纹理坐标节点(S_设备环境& ctx);
	~C_字符纹理坐标节点();

	S_Props m_坐标类型;

	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建字符纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载字符纹理坐标节点(S_设备环境& ctx, FILE* f);
void		f_node_保存字符纹理坐标节点(C_节点基类* n, FILE* f);



class API_EXPORT C_字符纹理排列节点 : public C_节点基类 {

public:
	C_字符纹理排列节点(S_设备环境& ctx);
	~C_字符纹理排列节点();

	S_Props m_排列方向;
	S_Props m_上下偏移;
	S_Props m_间隔;
	S_Props m_行距;
	S_Props m_缩放;
	
	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建字符纹理排列节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载字符纹理排列节点(S_设备环境& ctx, FILE* f);
void		f_node_保存字符纹理排列节点(C_节点基类* n, FILE* f);




class API_EXPORT C_重置纹理大小节点 : public C_节点基类 {
	S_纹理* m_新建纹理;
public:
	C_重置纹理大小节点(S_设备环境& ctx);
	~C_重置纹理大小节点();
	//S_Props m_导入纹理;
	//S_Props m_保存格式;
	S_Props m_复制;

	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建重置纹理大小节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载重置纹理大小节点(S_设备环境& ctx, FILE* f);
void		f_node_保存重置纹理大小节点(C_节点基类* n, FILE* f);



class API_EXPORT C_纹理写入文件节点 : public C_节点基类 {

public:
	C_纹理写入文件节点(S_设备环境& ctx);
	~C_纹理写入文件节点();

	S_Props m_保存格式;
	S_Props m_像素位宽;
	S_Props m_保存方式;

	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建纹理写入文件节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载纹理写入文件节点(S_设备环境& ctx, FILE* f);
void		f_node_保存纹理写入文件节点(C_节点基类* n, FILE* f);




class API_EXPORT C_取纹理属性节点 : public C_节点基类 {
	S_纹理* m_新建纹理;
public:
	C_取纹理属性节点(S_设备环境& ctx);
	~C_取纹理属性节点();

	//S_Props m_导入纹理;
	//S_Props m_保存格式;
	S_Props m_复制;

	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建取纹理属性节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载取纹理属性节点(S_设备环境& ctx, FILE* f);
void		f_node_保存取纹理属性节点(C_节点基类* n, FILE* f);



class API_EXPORT C_瓦片纹理坐标节点 : public C_节点基类 {
	
public:
	C_瓦片纹理坐标节点(S_设备环境& ctx);
	~C_瓦片纹理坐标节点();

	S_Props m_瓦片数量;
	S_Props m_瓦片大小;
	S_Props m_坐标类型;
	
	bool		f_update();
	std::string DEF_节点编译函数;

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建瓦片纹理坐标节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载瓦片纹理坐标节点(S_设备环境& ctx, FILE* f);
void		f_node_保存瓦片纹理坐标节点(C_节点基类* n, FILE* f);



